home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 3 / ct-rom iiib.zip / ct-rom iiib / WINDOWS / UTILITY / DESKTOP / CMAP / MAIN.CPP < prev    next >
C/C++ Source or Header  |  1994-05-08  |  5KB  |  169 lines

  1. #include <afxwin.h>
  2. #include <math.h>
  3. #include "main.h"
  4. /*
  5. This is a screen saver which uses colormap animation, a simple technique
  6. to achieve seemingly complicated motion.  The entire source of this
  7. program is provided for your convenience.  If you find it useful, I'll
  8. appreciate if you'll send me $10.  Send the check to:
  9.  
  10. CMAP registration
  11. c/o: Sin-Yaw Wang
  12. 5878 W. Walbrook Dr.
  13. San Jose, CA 95129
  14.  
  15. You can also contact me at sinyaw@netcom.com.
  16.  
  17. */
  18.  
  19. /////////////////////////////////////////////////////////////////////////////
  20.  
  21. // theApp:
  22. // Just creating this application object runs the whole application.
  23. //
  24. CTheApp theApp;
  25.  
  26. /////////////////////////////////////////////////////////////////////////////
  27.  
  28. // CMainWindow constructor:
  29. // Create the window with the appropriate style, size, menu, etc.
  30. //
  31. CMainWindow::CMainWindow():
  32.     timerid(7),     // randomly chosen id for timer
  33.     speed(15),        // how fast the animation is
  34.     cmap(NULL), entry(0), animate(0), cmap_size(0),
  35.     PI(acos(0)*2.0), INIT_PHASE(0)
  36. {
  37.     // create a rect which covers the whole screen
  38.     CRect rect(0, 0, 
  39.         GetSystemMetrics(SM_CXSCREEN),
  40.         GetSystemMetrics(SM_CYSCREEN));
  41.     Create( NULL, NULL, WS_POPUP | WS_VISIBLE, rect); 
  42. }
  43.  
  44. CMainWindow::~CMainWindow()
  45. {
  46.     delete cmap;
  47.     delete animate;
  48.     delete (char *)entry;
  49.     KillTimer(timerid);
  50. }
  51.  
  52. BOOL CMainWindow::OnEraseBkgnd(CDC *dc)
  53. {
  54.     CRect rect;
  55.     GetClientRect(&rect);
  56.     CBrush br;
  57.     int i = 0;
  58.  
  59.     // paint 256 rects with decreasing sizes with different colors
  60.     int dec = -1 * rect.Height() / 256;
  61.     CPalette *oldPal = dc->SelectPalette(cmap, FALSE);
  62.     dc->RealizePalette();
  63.     while (rect.Height() > 4) {
  64.         br.CreateSolidBrush(PALETTEINDEX(i++));
  65.         dc->FillRect(&rect, &br);
  66.         br.DeleteObject();
  67.         rect.InflateRect(dec, dec);
  68.         i %= 256;
  69.     }
  70.     dc->SelectPalette(oldPal, FALSE);
  71.     return TRUE;
  72. }
  73.  
  74. int CMainWindow::OnCreate(LPCREATESTRUCT lpCreate)
  75. {
  76.     CWindowDC dc(this);
  77.     cmap_size = dc.GetDeviceCaps(SIZEPALETTE);
  78.     cmap = new CPalette;
  79.     void  *data = new char[sizeof(LOGPALETTE) + 
  80.         cmap_size * sizeof(PALETTEENTRY)];
  81.     LOGPALETTE *entry = (LOGPALETTE *) data;
  82.     animate = new PALETTEENTRY[cmap_size];
  83.     ASSERT(cmap != NULL && data != NULL && animate != NULL);
  84.  
  85.     // smooth the color with cosine value with different phase angle
  86.     // this part is magic, you can experiment for different effects
  87.  
  88.     int r = 0, g = 0, b = 0;
  89.     double ang = 4.0 * PI / (double) cmap_size;
  90.     double rphase = INIT_PHASE;
  91.     double gphase = rphase + PI / 2.0;
  92.     double bphase = gphase + PI / 2.0;
  93.     entry->palVersion = 0x300;
  94.     entry->palNumEntries = cmap_size;
  95.     for (int i = 0; i < cmap_size; i++) {
  96.         entry->palPalEntry[i].peRed   = LOBYTE(127 + (int) (cos(rphase) * 127.0));
  97.         entry->palPalEntry[i].peGreen = LOBYTE(127 + (int) (cos(gphase) * 127.0));
  98.         entry->palPalEntry[i].peBlue  = LOBYTE(127 + (int) (cos(bphase) * 127.0));
  99.         entry->palPalEntry[i].peFlags = PC_RESERVED;
  100.         rphase += ang;
  101.         gphase += ang;
  102.         bphase += ang;
  103.     }
  104.  
  105.     // duplicate the colomap to seed the animation
  106.     for (i = 0; i < cmap_size; i++) {
  107.         animate[i].peRed = entry->palPalEntry[i].peRed;
  108.         animate[i].peGreen = entry->palPalEntry[i].peGreen;
  109.         animate[i].peBlue = entry->palPalEntry[i].peBlue;
  110.         animate[i].peFlags = PC_RESERVED;
  111.     }
  112.     
  113.     VERIFY(cmap->CreatePalette(entry));
  114.     VERIFY(SetTimer(timerid, speed, NULL));
  115.     return CWnd::OnCreate(lpCreate);
  116. }
  117.  
  118. void CMainWindow::OnTimer(UINT)
  119. {
  120.     // synthesize the next animation colormap and install it
  121.     PALETTEENTRY tmp;
  122.     int i = 0;
  123.     int last = cmap_size - 1;
  124.     tmp.peRed = animate[0].peRed;
  125.     tmp.peGreen = animate[0].peGreen;
  126.     tmp.peBlue = animate[0].peBlue;
  127.     for (i = 0; i < last; i++) {
  128.         animate[i].peRed = animate[i+1].peRed;
  129.         animate[i].peGreen = animate[i+1].peGreen;
  130.         animate[i].peBlue = animate[i+1].peBlue;
  131.         animate[i].peFlags = PC_RESERVED;
  132.     }
  133.     animate[i].peRed = tmp.peRed;
  134.     animate[i].peGreen = tmp.peGreen;
  135.     animate[i].peBlue = tmp.peBlue;
  136.     animate[i].peFlags = PC_RESERVED;
  137.     CWindowDC dc(this);
  138.     CPalette *oldPal = dc.SelectPalette(cmap, FALSE);
  139.     dc.RealizePalette();
  140.     cmap->AnimatePalette(0, cmap_size, animate);
  141.     dc.SelectPalette(oldPal, FALSE);
  142. }
  143.  
  144.  
  145. BEGIN_MESSAGE_MAP( CMainWindow, CScreenSaverWindow )
  146.     ON_WM_CREATE()
  147.     ON_WM_ERASEBKGND()
  148.     ON_WM_TIMER()
  149. END_MESSAGE_MAP()
  150.  
  151. BOOL CTheApp::InitInstance()
  152. {
  153.     if (m_hPrevInstance)
  154.             return FALSE;
  155.  
  156.     if (*m_lpCmdLine && *m_lpCmdLine == '-' || *m_lpCmdLine =='/') {
  157.         m_lpCmdLine++;
  158.         if (*m_lpCmdLine == 'c' || *m_lpCmdLine == 'C')
  159.             return FALSE;
  160.     }
  161.  
  162.     m_pMainWnd = new CMainWindow();
  163.     m_pMainWnd->ShowWindow( m_nCmdShow );
  164.     m_pMainWnd->UpdateWindow();
  165.  
  166.     return TRUE;
  167. }
  168.  
  169.